/*
 * XCMouse
 * http://code.google.com/p/bit-eclipse/wiki/XCMouse
 *
 * Copyright 2012, Denzel Morris
 * Licensed under the MIT License.
 * See License.txt
 */

#include <iostream>
#include <cmath>
#include "ControllerThread.h"
#include "ControllerState.h"

void HandleMouse(const ControllerState& s) {

	//
	// Convenient little array to map from my events to 
	// windows events (support user remapping later)
	//
	static const unsigned int bm[8][2] = {
		{ BUTTON_A_UP,   MOUSEEVENTF_LEFTUP },
		{ BUTTON_B_UP,   MOUSEEVENTF_RIGHTUP },
		{ BUTTON_X_UP,   0 },
		{ BUTTON_Y_UP,   0 },
		{ BUTTON_A_DOWN, MOUSEEVENTF_LEFTDOWN },
		{ BUTTON_B_DOWN, MOUSEEVENTF_RIGHTDOWN },
		{ BUTTON_X_DOWN, 0 },
		{ BUTTON_Y_DOWN, 0 }
	};

	INPUT in = {0};
	in.type = INPUT_MOUSE;
	
	const unsigned int flags = s.ButtonsFlag;
	for( int i = 0; i < 8; ++ i ) {
		//
		// A little masking bit trickery, just for fun
		//
		const unsigned int f = (flags & bm[i][0]) == 0; // 1 if nothing or 0 if something
		const unsigned int m = f - 1; // mask: 0x0 if nothing or 0xF if something
		in.mi.dwFlags |= bm[i][1] & m;
	}

	if( s.ldx != 0.f || s.ldy != 0.f ) {
		in.mi.dwFlags |= MOUSEEVENTF_MOVE;
		const float sx = s.ldx / std::abs(s.ldx);
		const float sy = s.ldy / std::abs(s.ldy);
		const float ldx = std::abs(s.ldx) + 0.22f;
		const float ldy = std::abs(s.ldy) + 0.22f;
		in.mi.dx = sx * (ldx * ldx * ldx) * 12.0f;
		in.mi.dy = sy * (ldy * ldy * ldy) * 12.0f;
	}

	//
	// Assume we have something to send even if we don't
	// Not a big deal, right?
	//
	SendInput(1, &in, sizeof(INPUT));
}

int main(int argc, char** argv) {
	ControllerThread cThread(&HandleMouse);
	cThread.start();

	while(1) {
		boost::thread::yield();
	}

	cThread.stop();

	return 0;
}